package com.zhuangjie.coupon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhaungjie.base.utils.BigDecimalUtils;
import com.zhuangjie.coupon.entity.CouponOrder;
import com.zhuangjie.coupon.entity.CouponProduct;
import com.zhuangjie.coupon.enums.CouponProductState;
import com.zhuangjie.coupon.lock.CouponOrderLock;
import com.zhuangjie.coupon.mapper.CouponOrderMapper;
import com.zhuangjie.coupon.pojo.CouponBatchAndLink;
import com.zhuangjie.coupon.service.CouponBatchService;
import com.zhuangjie.coupon.service.CouponOrderService;
import com.zhuangjie.coupon.service.CouponProductService;
import com.zhuangjie.coupon.vo.CouponOrderPayment;
import com.zhuangjie.security.provider.UserProvider;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zhuangjie
 * @since 2024-02-28
 */
@Service
public class CouponOrderServiceImpl extends ServiceImpl<CouponOrderMapper, CouponOrder> implements CouponOrderService {

    @Autowired
    private CouponProductService couponProductService;

    @Autowired
    private CouponBatchService couponBatchService;


    @Autowired
    private Redisson redisson;

    @Autowired
    private BigDecimalUtils bigDecimalUtils;

    @Override
    public CouponOrderPayment createCouponOrder(Long productOrderId) {
        Long userId = UserProvider.currentUserId();

        // 查找是否有相同的旧订单
        LambdaQueryWrapper<CouponOrder> queryExistingSameOrder = Wrappers.lambdaQuery(CouponOrder.class)
                .eq(CouponOrder::getUserId, userId)
                .eq(CouponOrder::getCouponProductId, productOrderId)
                .eq(CouponOrder::getState, CouponProductState.WAITING_PAYMENT.getCode());
        CouponOrder couponOrder = this.getOne(queryExistingSameOrder);
        if (couponOrder == null) {
            // 查询product
            CouponProduct couponProduct = couponProductService.getById(productOrderId);
            // 创建新订单
            couponOrder = new CouponOrder();
            couponOrder.setState(CouponProductState.WAITING_PAYMENT.getCode());
            couponOrder.setUserId(userId);
            couponOrder.setCouponProductId(productOrderId);
            couponOrder.setPaymentAmount(bigDecimalUtils.subtractionOperation(couponProduct.getPrice(),couponProduct.getPreferential()));
            this.save(couponOrder);
        }
        // 创建返回支付信息与参数
        CouponOrderPayment couponOrderPayment = new CouponOrderPayment();
        couponOrderPayment.setOrderId(couponOrder.getId());
        couponOrderPayment.setPaymentAmount(couponOrder.getPaymentAmount());

        // TODO... 添加支付相关参数
        return couponOrderPayment;
    }



    @Override
    @Transactional
    public void paymentCouponOrder(Long orderId) {
        // 真实的，会校验再进行修饰支付订单

        // 加锁修饰订单状态
        RLock lock = redisson.getLock(CouponOrderLock.getCouponOrderOperationLock(orderId));
        lock.lock();
        try {
            LambdaUpdateWrapper<CouponOrder> couponOrderLambdaUpdateWrapper = Wrappers.lambdaUpdate(CouponOrder.class)
                    .eq(CouponOrder::getId, orderId)
                    .eq(CouponOrder::getState, CouponProductState.WAITING_PAYMENT.getCode())
                    .set(CouponOrder::getState, CouponProductState.PURCHASED.getCode());
            boolean updateSuccess = this.update(couponOrderLambdaUpdateWrapper);
            if (!updateSuccess) {
                throw new RuntimeException("订单支付完成处理失败！状态可能已经改变");
            }
            // 将订单的优惠卷的发到账户中
            // 查询订单中是哪个优惠卷产品
            CouponOrder couponOrder = this.getById(orderId);
            // 查询订单中的产品涉及的优惠卷
            List<CouponBatchAndLink> couponBatchAndLinks = couponProductService.queryCouponProductById(couponOrder.getCouponProductId());
            if (couponBatchAndLinks == null || couponBatchAndLinks.isEmpty()) {
                throw new RuntimeException("优惠卷产品无券！");
            }
            // 批量发优惠卷
            Long currentUserId = UserProvider.currentUserId();
            for (CouponBatchAndLink couponBatchAndLink : couponBatchAndLinks) {
                // 发优惠卷给用户
                couponBatchService.sendCouponToUser(couponBatchAndLink,couponBatchAndLink.getNumber(),currentUserId);
            }
        }catch (Exception e){
            // TODO 请求支付模块给用户退款
            // ...
            throw new RuntimeException();
        } finally {
            lock.unlock();
        }


    }
}
